﻿//TODO: FreiChenFilter, Test
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Frei chen filter
    /// The final pixel value is the ratio between the mulitiplication of four kernals 
    /// with the surrounding pixel neighborhood and the square sum of all pixels. 
    /// The following are the kernals used to multiply the pixel neighborhood: 
    /// </summary>
    public class FreiChenFilter : BaseImageFilter
    {
        protected int m_nUsedKernels = 1;

        protected OwnOptimizedConvolutionInt m_OwnOptimizedConvolution = new OwnOptimizedConvolutionInt();

        protected int[,] aKernel1 = new int[,] {
                    {2,3,4 },
                    {0,0,0},
                    {-2,-3,-4}};

        protected int[,] aKernel2 = new int[,] {
                    {2,0,-2 },
                    {0,-2,3},
                    {-2,-3,-2}};

        protected int[,] aKernel3 = new int[,] {
                    {3,0,-3 },
                    {2,0,-2},
                    {-2,0,-2}};

        protected int[,] aKernel4 = new int[,] {
                    {2,0,-2 },
                    {-3,2,0},
                    {0,2,-3}};


        /// <summary>
        /// Default constructor
        /// </summary>
        public FreiChenFilter()
        {
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_freiChenFilter"></param>
        internal FreiChenFilter(FreiChenFilter _freiChenFilter)
        {
        }

        /// <summary>
        /// Gets or sets the used kernels.
        /// </summary>
        /// <value>The used kernels.</value>
        public int UsedKernels
        {
            get { return m_nUsedKernels; }
            set { m_nUsedKernels = value; }
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            //TODO: normally square sum is needed here 
            if ((m_nUsedKernels & 1) == 1)
            {
                m_OwnOptimizedConvolution.Kernel = aKernel1;
                m_OwnOptimizedConvolution.Execute(_bitmap);
            }

            if ((m_nUsedKernels & 2) == 2)
            {
                m_OwnOptimizedConvolution.Kernel = aKernel2;
                m_OwnOptimizedConvolution.Execute(_bitmap);
            }

            if ((m_nUsedKernels & 4) == 4)
            {
                m_OwnOptimizedConvolution.Kernel = aKernel3;
                m_OwnOptimizedConvolution.Execute(_bitmap);
            }

            if ((m_nUsedKernels & 8) == 8)
            {
                m_OwnOptimizedConvolution.Kernel = aKernel4;
                m_OwnOptimizedConvolution.Execute(_bitmap);
            }
            return _bitmap;
        }

        /// <summary>
        /// used to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new FreiChenFilter(this);
        }
    }
}
